#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "CallAction.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class InputPin;
class Operation;
class Parameter;

/// <summary>
/// CallOperationAction
/// A CallOperationAction is a CallAction that transmits an Operation call request
/// to the target object, where it may cause the invocation of associated Behavior.
/// The argument values of the CallOperationAction are passed on the input
/// Parameters of the Operation. If call is synchronous, the execution of the
/// CallOperationAction waits until the execution of the invoked Operation completes
/// and the values of output Parameters of the Operation are placed on the result
/// OutputPins. If the call is asynchronous, the CallOperationAction completes
/// immediately and no results values can be provided.
/// </summary>
class UMLMODEL_EXPORT CallOperationAction : public CallAction {

public: // Constructors and destructors
    explicit CallOperationAction(const QString& umlType="uml::CallOperationAction");

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Methods
    /// <summary>
    /// outputParameters
    /// Return the inout, out and return ownedParameters of the Operation being called.
    /// </summary>
    shared_ptr<vector<Parameter>> outputParameters() const override;

    /// <summary>
    /// inputParameters
    /// Return the in and inout ownedParameters of the Operation being called.
    /// </summary>
    shared_ptr<vector<Parameter>> inputParameters() const override;

public: // Properties
    /// <summary>
    /// operation getter
    /// The Operation being invoked.
    /// </summary>
    shared_ptr<Operation> operation() const;

    /// <summary>
    /// operation setter
    /// The Operation being invoked.
    /// </summary>
    void setOperation(shared_ptr<Operation> value);

    /// <summary>
    /// target getter
    /// The InputPin that provides the target object to which the Operation call request
    /// is sent.
    /// </summary>
    shared_ptr<InputPin> target() const;

    /// <summary>
    /// target setter
    /// The InputPin that provides the target object to which the Operation call request
    /// is sent.
    /// </summary>
    void setTarget(shared_ptr<InputPin> value);

private: // Fields
    /// <summary>
    /// operation
    /// The Operation being invoked.
    /// </summary>
    shared_ptr<Operation> operation_;

    /// <summary>
    /// target
    /// The InputPin that provides the target object to which the Operation call request
    /// is sent.
    /// </summary>
    shared_ptr<InputPin> target_;

};

} // namespace uml
